package com.shotnshare.app;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.Window;
import com.google.ads.AdRequest;
import com.google.ads.AdView;

public class New_FirstScreen extends SherlockActivity implements Callback {

	private SharedPreferences sharedPrefs;
	private SharedPreferences.Editor sharedPrefsEditor;

	PackageManager pm;

	boolean hasFlash = true;
	boolean hasFrontC = true, hasBackC = true;
	private boolean isBackCamera;
	private boolean isBurstMode;
	private int currentCameraID = 0;

	CountDownTimer counter;

	boolean autoShot, silentMode, autoSave;
	int delayTime, burstMode;

	int stillCount;

	// to set animation when clicking button
	AlphaAnimation alphaDown = new AlphaAnimation(1.0f, 0.5f);

	// Variable -CAMERA
	Camera camera;
	int MAX_PIC_WIDTH_VALUE = 1500;
	double MIN_PIC_RATIO = 0.7;
	int MAX_PREVIEWVALUE = 1500;

	SurfaceView surfaceView;
	SurfaceHolder surfaceHolder;
	boolean previewing = false;
	byte[] byteArray; // one image

	// Variable -FLASH
	// 0 - Off, 1 - On, 2 - Auto
	int flashMode;

	// Variable -SENSOR
	OrientationEventListener myOrientationEventListener;
	private float currentDegree;

	Activity activity;

	/*
	 * Dung: variable int nPic: default = 1 sound: default = true flash: default
	 * = auto {auto,on,off -> attribute of camera.parameter} count down: default
	 * = 0 {0,3,4,5} delay: default = 1 if in n pic mode
	 */

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		activity = this;
		stillCount = 0;
		// hide title
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		super.onCreate(savedInstanceState);

		// Set full screen view
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		// Other inits
		Context context = this;
		setContentView(R.layout.new_activity_first_screen);
		SetBrightness();

		if (!Check_Device(context)) {
			Toast.makeText(getBaseContext(), "Device no have camera",
					Toast.LENGTH_LONG).show();
			finish();
		}

		Count_Down_Init();

		Load_Ads();

		LoadSettings();

		if (hasBackC == false) {
			isBackCamera = false;
		}

		// Buttons init
		Control_Settings();
		Control_Flash();
		Control_AutoShot();
		Control_FrontBack();
		Control_BurstMode();
		Control_Shutter();

		initSensor();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		counter.cancel();
		final TextView t = (TextView) findViewById(R.id.countdown_display);
		t.setText("");
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		LoadPreview();

		if (camera != null) {
			this.reinitCamera();
		} else {
			camera = getCameraInstance();
			this.initCameraParameter();
			this.checkFlash();
		}

		if (camera == null) {
			Toast.makeText(getBaseContext(), "Can't access camera!",
					Toast.LENGTH_SHORT).show();
			finish();
		}

		// Log.i("onResume", "onResume");
	}
	ImageButton btFlash;
	private void checkFlash() {
		if (this.camera != null) {
			btFlash = (ImageButton) findViewById(R.id.button_Flash);
			// Check flash
			if (camera.getParameters().getFlashMode() == null) {
				hasFlash = false;
				btFlash.setImageResource(R.drawable.ic_access_flash_off);
				btFlash.setEnabled(false);
				flashMode = 0;
			} else {
				this.flashMode = this.sharedPrefs.getInt("flashMode", 2);

				if (this.flashMode == 0) {
					btFlash.setImageResource(R.drawable.ic_access_flash_off);
				} else if (this.flashMode == 1) {
					btFlash.setImageResource(R.drawable.ic_access_flash_on);
				} else {
					btFlash.setImageResource(R.drawable.ic_access_flash_auto);
				}

				btFlash.setEnabled(true);
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return true;
	}

	private void SetBrightness() {
		WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
		layoutParams.screenBrightness = 1;
		getWindow().setAttributes(layoutParams);
	}

	private boolean Check_Device(Context context) {

		int numCamera = 0;
		// Check camera
		pm = context.getPackageManager();

		if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
			numCamera = numCamera + 1;
		} else {
			hasBackC = false;
		}

		if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
			numCamera = numCamera + 1;
		} else {
			hasFrontC = false;
		}

		if (numCamera > 0) {
			return true;
		} else {
			return false;
		}
	}

	// BEGIN SENSOR

	private ArrayList<android.view.View> rotatedElements = new ArrayList<android.view.View>();

	private Animation getRotatingAnimation(float fromDeg, float toDeg, long duration) {
		Animation ani = new RotateAnimation(fromDeg, toDeg,
				Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		ani.setDuration(duration);
		ani.setFillAfter(true);
		ani.setInterpolator(new LinearInterpolator());

		return ani;
	}

	private void ApplyAnimation(float fromDeg, float toDeg) {

		int size = rotatedElements.size();
		for (int i = 0; i < size; i++) {
			rotatedElements.get(i).startAnimation(
					getRotatingAnimation(fromDeg, toDeg, 150));
		}

	}

	private void initSensor() {

		currentDegree = 0;

		rotatedElements.add((ImageButton) findViewById(R.id.button_N_Images));
		rotatedElements.add((ImageButton) findViewById(R.id.button_Flash));
		rotatedElements.add((ImageButton) findViewById(R.id.button_Capture));
		rotatedElements.add((ImageButton) findViewById(R.id.button_Front_Back));
		rotatedElements.add((ImageButton) findViewById(R.id.button_Setting));
		rotatedElements.add((ImageView) findViewById(R.id.img_Count_Down));
		rotatedElements.add((TextView) findViewById(R.id.countdown_display));

		myOrientationEventListener = new OrientationEventListener(this,
				SensorManager.SENSOR_DELAY_NORMAL) {
			@Override
			public void onOrientationChanged(int degree) {

				if (45 <= degree && degree < 135) {
					if (currentDegree != -90) {
						ApplyAnimation(currentDegree, -90);
						currentDegree = -90;
					}
				} else if (135 <= degree && degree < 225) {
					if (currentDegree != 180) {
						ApplyAnimation(currentDegree, 180);
						currentDegree = 180;
					}
				} else if (225 <= degree && degree < 315) {
					if (currentDegree != 90) {
						ApplyAnimation(currentDegree, 90);
						currentDegree = 90;
					}
				} else {
					if (currentDegree != 0) {
						ApplyAnimation(currentDegree, 0);
						currentDegree = 0;
					}
				}
			}
		};

		if (myOrientationEventListener.canDetectOrientation()) {
			// Toast.makeText(this, "Can DetectOrientation",
			// Toast.LENGTH_LONG).show();
			myOrientationEventListener.enable();
		} else {
			// Toast.makeText(this, "Can't DetectOrientation",
			// Toast.LENGTH_LONG).show();
			finish();
		}

	}

	// END SENSOR

	private void Count_Down_Init() {
		counter = new CountDownTimer(6000, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onFinish() {
				// TODO Auto-generated method stub

			}
		};
	}

	private void LoadSettings() {
		// Get preference: autoshotMode? delayTime ; burstMode ; silentMode?
		// saving Location
		this.sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
		this.sharedPrefsEditor = this.sharedPrefs.edit();

		autoShot = sharedPrefs.getBoolean("pref_autoshot_mode", false);
		if (autoShot)
			delayTime = Integer.parseInt(sharedPrefs.getString("pref_timer",
					"3"));

		burstMode = Integer.parseInt(sharedPrefs.getString("pref_burst_mode",
				"2"));
		silentMode = sharedPrefs.getBoolean("pref_silent_mode", false);
		silentMode = !silentMode;
		autoSave = sharedPrefs.getBoolean("pref_save_picture", true);

		this.isBackCamera = sharedPrefs.getBoolean("isBackCamera", true);
		this.isBurstMode = sharedPrefs.getBoolean("isBurstMode", false);
	}

	private void Load_Ads() {

		AdView adView = null;
		if (adView == null) {
			adView = (AdView) this.findViewById(R.id.adsImage);
		}
		AdRequest ar = new AdRequest();
		//ar.addTestDevice(AdRequest.TEST_EMULATOR);
		/*ar.addTestDevice("YT9101D530"); // Sony
		ar.addTestDevice("HT265W507354");
		ar.addTestDevice("SH35JVV00526"); // Tri
		ar.addTestDevice("323150C41B6900EC"); // Client
		ar.addTestDevice("c1607d41105938f"); // My*/
		adView.loadAd(ar);

	}

	// CAMERA

	public Camera getCameraInstance() {
		Camera c = null;
		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		int cameraCount = 0;

		try {
			cameraCount = Camera.getNumberOfCameras();

			for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
				Camera.getCameraInfo(camIdx, cameraInfo);
				if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK
						&& isBackCamera == true) {
					try {
						c = Camera.open(camIdx);
						this.currentCameraID = camIdx;
						break;
					} catch (RuntimeException e) {
						// Log.e(TAG, "Camera failed to open: " +
						// e.getLocalizedMessage());
					}
				} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT
						&& isBackCamera == false) {
					try {
						c = Camera.open(camIdx);
						this.currentCameraID = camIdx;
						break;
					} catch (RuntimeException e) {
					}
				}
			}

			// c = Camera.open();// attempt to get a Camera instance
		} catch (Exception e) {

		}

		return c; // returns null if camera is unavailable
	}

	private void LoadPreview() {
		getWindow().setFormat(PixelFormat.UNKNOWN);
		surfaceView = (SurfaceView) findViewById(R.id.surface_View);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	private void Control_Flash() {
		final ImageButton btFlash = (ImageButton) findViewById(R.id.button_Flash);

		if (!hasFlash)
			btFlash.setImageResource(R.drawable.ic_access_flash_off);
		else {
			/*
			 * btFlash.setImageResource(R.drawable.ic_access_flash_auto);
			 * flashMode=0;
			 */

			btFlash.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {

					v.setAnimation(alphaDown);

					New_FirstScreen.this.flashMode = (New_FirstScreen.this.flashMode + 1) % 3;
					New_FirstScreen.this.sharedPrefsEditor.putInt("flashMode",
							New_FirstScreen.this.flashMode);
					New_FirstScreen.this.sharedPrefsEditor.commit();

					if (New_FirstScreen.this.flashMode == 0) {

						btFlash.setImageResource(R.drawable.ic_access_flash_off);

					} else if (New_FirstScreen.this.flashMode == 1) {

						btFlash.setImageResource(R.drawable.ic_access_flash_on);

					}
					if (New_FirstScreen.this.flashMode == 2) {

						btFlash.setImageResource(R.drawable.ic_access_flash_auto);

					}
					
					btFlash.startAnimation(getRotatingAnimation(currentDegree, currentDegree, 0));
					
				}
			});

		}

	}

	private void Control_AutoShot() {
		ImageView imgCountDown = (ImageView) findViewById(R.id.img_Count_Down);
		if (autoShot) {
			switch (delayTime) {
			case 3:
				imgCountDown.setImageResource(R.drawable.ic_time_3);
				break;
			case 4:
				imgCountDown.setImageResource(R.drawable.ic_time_4);
				break;
			case 5:
				imgCountDown.setImageResource(R.drawable.ic_time_5);
				break;
			}
		} else
			imgCountDown.setImageResource(R.drawable.ic_time_off);
	}
	ImageButton btFB;
	private void Control_FrontBack() {
		btFB = (ImageButton) findViewById(R.id.button_Front_Back);

		if (hasBackC && hasFrontC) {
			btFB.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View arg0) {
					//arg0.setAnimation(alphaDown);
					// TODO Auto-generated method stub
					isBackCamera = !isBackCamera;
					New_FirstScreen.this.sharedPrefsEditor.putBoolean(
							"isBackCamera", isBackCamera);
					New_FirstScreen.this.sharedPrefsEditor.commit();
					New_FirstScreen.this.reinitCamera();
				}
			});
		} else {
			btFB.setEnabled(false);
		}
	}
	ImageButton btSetting;
	private void Control_Settings() {
		btSetting = (ImageButton) findViewById(R.id.button_Setting);
		btSetting.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent in1 = new Intent(getApplicationContext(),
						SettingScreen.class);
				in1.putExtra("from_screen", 1);

				// Effect when clicking button
				v.startAnimation(alphaDown);

				startActivity(in1);

			}
		});
	}

	private void Control_Shutter() {

		final ImageButton btCamera = (ImageButton) findViewById(R.id.button_Capture);
		btCamera.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				v.setAnimation(alphaDown);

				//btCamera.setEnabled(false);

				// parameter set-flash
				// ...
				if (autoShot) {

				//	btCamera.setEnabled(true);

					int time_;
					try {
						time_ = (delayTime + 1) * 1000;
					} catch (Exception e) {
						// TODO: handle exception
						time_ = 1000;
					}
					counter.cancel();

					Toast.makeText(getBaseContext(), "Start", Toast.LENGTH_LONG)
							.show();
					counter = new CountDownTimer(time_, 1000) {
						@Override
						public void onTick(long arg0) {
							// TODO Auto-generated method stub

							// Dung: To make sure count down time right. Don't
							// forgot: cha hiu de lam gi ma ko co thi ko dc
							// Toast.makeText(getBaseContext(), "False",
							// Toast.LENGTH_SHORT);

							final TextView t = (TextView) findViewById(R.id.countdown_display);
							t.setText("" + arg0 / 1000 + "s");
							// Toast.makeText(getBaseContext(), "" + arg0/1000
							// +"s", Toast.LENGTH_LONG).show();

						}

						@Override
						public void onFinish() {
							// TODsO Auto-generated method stub
							TextView t = (TextView) findViewById(R.id.countdown_display);
							t.setText("");

							SayCheese();

						//	btCamera.setEnabled(false);
						}
					};

					counter.start();
				} else {
					SayCheese();
				}
				btCamera.setEnabled(false);
				btNImages.setEnabled(false);
				btSetting.setEnabled(false);
				btFlash.setEnabled(false);
				btFB.setEnabled(false);
			}
		});
	}
	
	ImageButton btNImages;
	private void Control_BurstMode() {
		 btNImages = (ImageButton) findViewById(R.id.button_N_Images);

		if (isBurstMode == false) {
			btNImages.setImageResource(R.drawable.ic_burst_off);
		} else {
			if (burstMode == 2)
				btNImages.setImageResource(R.drawable.ic_burst_2);
			else if (burstMode == 4)
				btNImages.setImageResource(R.drawable.ic_burst_4);
			else if (burstMode == 6)
				btNImages.setImageResource(R.drawable.ic_burst_6);
			else if (burstMode == 8)
				btNImages.setImageResource(R.drawable.ic_burst_8);
			else if (burstMode == 10)
				btNImages.setImageResource(R.drawable.ic_burst_10);
		}

		btNImages.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				// Effect when clicking button

				v.startAnimation(alphaDown);
				isBurstMode = !isBurstMode;
				New_FirstScreen.this.sharedPrefsEditor.putBoolean(
						"isBurstMode", isBurstMode);
				New_FirstScreen.this.sharedPrefsEditor.commit();

				if (isBurstMode == false) {
					btNImages.setImageResource(R.drawable.ic_burst_off);
				} else {
					if (burstMode == 2)
						btNImages.setImageResource(R.drawable.ic_burst_2);
					else if (burstMode == 4)
						btNImages.setImageResource(R.drawable.ic_burst_4);
					else if (burstMode == 6)
						btNImages.setImageResource(R.drawable.ic_burst_6);
					else if (burstMode == 8)
						btNImages.setImageResource(R.drawable.ic_burst_8);
					else if (burstMode == 10)
						btNImages.setImageResource(R.drawable.ic_burst_10);
				}
				
				btNImages.startAnimation(getRotatingAnimation(currentDegree, currentDegree, 0));
			}
		});
	}

	/*
	 * CAMERA FUNCTION - SURFACE IMPLEMENTS: surfaceChanged; surfaceCreated;
	 * surfaceDestroyed
	 */

	private void SayCheese() {

		// check silent mode
		if (silentMode == false) {
			MediaPlayer.create(New_FirstScreen.this, R.raw.beep).start();
		} else {
			AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
			audio.setStreamVolume(AudioManager.STREAM_SYSTEM, 0,
					AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
		}

		Camera.Parameters parameters = camera.getParameters();
		/*
		 * if ((currentDegree == 90)) parameters.setRotation(0); else if
		 * (currentDegree == 0) parameters.setRotation(90); else if
		 * (currentDegree == -90) parameters.setRotation(180); else if
		 * (currentDegree == 180) parameters.setRotation(90);
		 */
		if (hasFlash == true) {

			if (this.flashMode == 0) {
				parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
			} else if (this.flashMode == 1) {
				parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
			} else {
				parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
			}

		}

		camera.setParameters(parameters);
		camera.takePicture(null, myPictureCallback_RAW, myPictureCallback_JPG);

	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		if (previewing) {
			camera.stopPreview();
			previewing = false;
		}
		if (camera != null) {
			try {
				// Log.i("surfaceChanged", "surfaceChanged");
				camera.setPreviewDisplay(surfaceHolder);
				camera.startPreview();
				previewing = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private double getScreenAspectRatio() {

		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int height = displaymetrics.heightPixels;
		int width = displaymetrics.widthPixels;

		double result = 0;

		if (width < height) {
			result = (double) width / height;
		} else {
			result = (double) height / width;
		}

		result = Math.round(result * 100.0) / 100.0;

		return result;

	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		camera.stopPreview();
		camera.release();
		camera = null;
		previewing = false;
	}

	// Re Initialize Camera when value is not null
	private void reinitCamera() {

		if (this.camera != null) {

			surfaceHolder.removeCallback(New_FirstScreen.this);
			surfaceHolder = null;
			LoadPreview();

			if (previewing == true) {
				camera.stopPreview();
				camera.setPreviewCallback(null);
			}

			camera.release();
			camera = null;
			camera = getCameraInstance();
			this.initCameraParameter();

			setCameraDisplayOrientation(New_FirstScreen.this, currentCameraID,
					camera);

			if (camera != null) {
				try {
					camera.setPreviewDisplay(New_FirstScreen.this.surfaceHolder);
					camera.startPreview();
					previewing = true;
					this.checkFlash();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
	}

	private void initCameraParameter() {
		Camera.CameraInfo info = new Camera.CameraInfo();
		Camera.getCameraInfo(this.currentCameraID, info);
		setCameraDisplayOrientation(this, this.currentCameraID, this.camera);

		Camera.Parameters parameters = camera.getParameters();
		parameters.set("jpeg-quality", 100);

		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int screenWidth = displaymetrics.widthPixels;

		// Log.i("screenWidth", "" + screenWidth);
		// Toast.makeText(getBaseContext(), "screenWidth: " + screenWidth,
		// Toast.LENGTH_LONG).show();

		List<Camera.Size> lstPicSizes = parameters.getSupportedPictureSizes();
		List<Camera.Size> lstPreviewSizes = parameters
				.getSupportedPreviewSizes();

		Camera.Size pictureSize = lstPicSizes.get(0);
		Camera.Size previewSize = null;
		final double screenAspectRatio = getScreenAspectRatio();

		// Log.i("screenAspectRatio", "" + screenAspectRatio);

		/*
		 * boolean isWidthLargerThanHeight = true;
		 * 
		 * for(Camera.Size s:lstPicSizes){ if ( s.width != s.height){ if
		 * (s.width < s.height){ isWidthLargerThanHeight = false; } break; } }
		 */

		if (isBackCamera == true) {
			final ArrayList<Double> lstPicRatio = new ArrayList<Double>();

			for (Camera.Size s : lstPicSizes) {
				double ratio = (double) s.height / s.width;
				ratio = Math.round(ratio * 100.0) / 100.0;
				lstPicRatio.add(ratio);
			}

			// PICTURE SIZE
			for (int i = lstPicSizes.size() - 1; i >= 0; i--) {
				Camera.Size s = lstPicSizes.get(i);
				if (s.width > MAX_PIC_WIDTH_VALUE
						|| lstPicRatio.get(i) < MIN_PIC_RATIO) {
					lstPicSizes.remove(i);
					lstPicRatio.remove(i);
				}
			}

			pictureSize = lstPicSizes.get(0);
			// final double final_pic_ratio = lstPicRatio.get(0);
			/*
			 * for (Camera.Size s:lstPicSizes){ double s1Ratio = (double)
			 * s.height / s.width; s1Ratio = Math.round( s1Ratio * 100.0 ) /
			 * 100.0; //Log.i("pic", "" + s.width + ":" + s.height + ":" +
			 * s1Ratio); }
			 */

			// PREVIEW SIZE
			for (int i = lstPreviewSizes.size() - 1; i >= 0; i--) {
				Camera.Size s = lstPreviewSizes.get(i);
				if (s.width > MAX_PREVIEWVALUE) {
					lstPreviewSizes.remove(i);
				}
			}

			Collections.sort(lstPreviewSizes, new Comparator<Camera.Size>() {
				@Override
				public int compare(Camera.Size s1, Camera.Size s2) {
					double s1Ratio = (double) s1.height / s1.width;
					s1Ratio = Math.round(s1Ratio * 100.0) / 100.0;
					s1Ratio = Math.abs(s1Ratio - screenAspectRatio);

					double s2Ratio = (double) s2.height / s2.width;
					s2Ratio = Math.round(s2Ratio * 100.0) / 100.0;
					s2Ratio = Math.abs(s2Ratio - screenAspectRatio);

					return (s1Ratio > s2Ratio) ? 1 : (s1Ratio < s2Ratio) ? -1
							: 0;
				}
			});

			previewSize = lstPreviewSizes.get(0);
			/*
			 * for (Camera.Size s:lstPreviewSizes){ double s1Ratio = (double)
			 * s.height / s.width; s1Ratio = Math.round( s1Ratio * 100.0 ) /
			 * 100.0; //Log.i("preview", "" + s.width + ":" + s.height + ":" +
			 * s1Ratio); }
			 */
		} else {
			previewSize = lstPreviewSizes.get(0);
			pictureSize = lstPicSizes.get(0);
		}

		parameters.setPictureSize(pictureSize.width, pictureSize.height);
		parameters.setPreviewSize(previewSize.width, previewSize.height);

		Log.i("picture", "" + pictureSize.width + ":" + pictureSize.height
				+ ":" + (double) pictureSize.height / pictureSize.width);
		Log.i("preview", "" + previewSize.width + ":" + previewSize.height
				+ ":" + (double) previewSize.height / previewSize.width);

		// Image's format
		parameters.setPictureFormat(PixelFormat.JPEG);

		camera.setParameters(parameters);

		// Init Preview Holder
		double realHeight = (double) screenWidth / previewSize.height;
		realHeight = realHeight * previewSize.width;

		ViewGroup.LayoutParams params = surfaceView.getLayoutParams();
		params.height = (int) realHeight;
		surfaceView.setLayoutParams(params);
	}

	// Control camera preview when rotate
	public static void setCameraDisplayOrientation(Activity activity,
			int cameraId, android.hardware.Camera camera) {
		android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
		android.hardware.Camera.getCameraInfo(cameraId, info);
		int rotation = activity.getWindowManager().getDefaultDisplay()
				.getRotation();
		int degrees = 0;
		switch (rotation) {
		case Surface.ROTATION_0:
			degrees = 0;
			break;
		case Surface.ROTATION_90:
			degrees = 90;
			break;
		case Surface.ROTATION_180:
			degrees = 180;
			break;
		case Surface.ROTATION_270:
			degrees = 270;
			break;
		}

		int result;
		if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
			result = (info.orientation + degrees) % 360;
			result = (360 - result) % 360; // compensate the mirror
		} else { // back-facing
			result = (info.orientation - degrees + 360) % 360;
		}
		camera.setDisplayOrientation(result);
	}

	/*
	 * ShutterCallback, PictureCallback for RAW and PictureCallback for JPG To
	 * take picture, simple call camera.takePicture() method passing with the
	 * Callbacks.
	 */
	ShutterCallback myShutterCallback = new ShutterCallback() {

		@Override
		public void onShutter() {

		}
	};

	PictureCallback myPictureCallback_RAW = new PictureCallback() {

		// control img rotate
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
		}
	};

	// Array of paths for 2nd view
	private ArrayList<String> burstmode_images = new ArrayList<String>();

	// Save as JPG
	PictureCallback myPictureCallback_JPG = new PictureCallback() {
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {

			if (isBurstMode == false) { // save tmp file go to 3rd screen
				Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0,
						data.length);
				bitmapPicture = rotateImage(bitmapPicture);

				File pictureFile = getOutputMediaFile();

				if (pictureFile == null) {
					return;
				}

				try {
					FileOutputStream fos = new FileOutputStream(pictureFile);
					// fos.write(data);
					bitmapPicture
							.compress(Bitmap.CompressFormat.JPEG, 100, fos);
					fos.flush();
					fos.close();

					Intent in1 = new Intent(activity, EffectScreen.class);
					in1.putExtra("from_screen", 1);
					in1.putExtra("auto_save", autoSave);
					in1.putExtra("image", pictureFile.getPath());
					startActivity(in1);
				} catch (FileNotFoundException e) {

				} catch (IOException e) {

				}
			} // End if isBurstMode
			else {
				// continue shutter
				try {
					Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data,
							0, data.length);
					bitmapPicture = rotateImage(bitmapPicture);
					File pictureFile = getOutputMediaFile();

					if (pictureFile == null) {
						return;
					}
					try {

						FileOutputStream fos = new FileOutputStream(pictureFile);
						// fos.write(data);
						bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 80,
								fos);
						fos.flush();
						fos.close();
						New_FirstScreen.this.burstmode_images.add(pictureFile
								.getPath());

					} catch (Exception e) {

					}

					stillCount++;
					camera.startPreview();
					// delay 2s
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					if (stillCount < burstMode) {
						// Repeat SayCheese until the end.
						SayCheese();
					}

					if (stillCount == burstMode) {

						// go to 2nd view
						Intent image_screen_intent = new Intent(activity,
								ImageScreen.class);
						image_screen_intent
								.putExtra(
										"image_list",
										(ArrayList<String>) New_FirstScreen.this.burstmode_images);
						startActivity(image_screen_intent);

					}
				} catch (Exception e) {

				}
			} // End else isBurstMode
		} // End void
	};

	private Bitmap rotateImage(Bitmap bitmap) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		int degreeBitmap = 0;
		if ((currentDegree == 90))
			degreeBitmap = 0;
		else if (currentDegree == 0)
			degreeBitmap = 90;
		else if (currentDegree == -90)
			degreeBitmap = 180;
		else if (currentDegree == 180)
			degreeBitmap = 90;

		Matrix mtx = new Matrix();
		// mtx.postRotate(degree);
		mtx.setRotate(degreeBitmap);
		if (!isBackCamera) {
			if (currentDegree == 0)
				mtx.preRotate(180);
			else if (currentDegree == 180)
				mtx.preRotate(180);
		}
		return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
	}

	/** Create a File for saving the image */
	private static File getOutputMediaFile() {

		File mediaStorageDir = new File(
				Environment
						.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
				"ShotnShare");

		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdirs()) {
				return null;
			}
		}

		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
				.format(new Date());
		File mediaFile;
		mediaFile = new File(mediaStorageDir.getPath() + File.separator
				+ "IMG_" + timeStamp + ".jpg");

		return mediaFile;
	}

	/* END CODE CAMERA FUNCTION */

}
